package org.aplikator.client.shared.rpc.marshaller;

import org.aplikator.client.shared.descriptor.ClientDescriptorBase;
import org.jboss.errai.marshalling.client.api.Marshaller;
import org.jboss.errai.marshalling.client.api.MarshallingSession;
import org.jboss.errai.marshalling.client.api.json.EJArray;
import org.jboss.errai.marshalling.client.api.json.EJObject;
import org.jboss.errai.marshalling.client.api.json.EJString;
import org.jboss.errai.marshalling.client.api.json.EJValue;

import sun.security.krb5.internal.APOptions;

import java.util.*;

@SuppressWarnings("unchecked")
public class DemarshallingUtils {
	
	public static Map mapUnMarshall(EJValue o, MarshallingSession ctx, String encName) {
		if (o.isObject() != null) {
			Map map = new HashMap();
			Marshaller<Object> marsh = ctx.getMarshallerInstance(encName);
			EJObject object = o.isObject();
			Set<String> ks = object.keySet();
			for (String k : ks) {
				EJValue ejval = object.get(k);
				map.put(k, marsh.demarshall(ejval, ctx));
			}
			return map;
		} else return new HashMap();
	}

	
	public static void clientDescriptorBaseUnMarshall(EJObject object, ClientDescriptorBase cdb) {
		String id = DemarshallingUtils.safeString(object, "id");
		String localizedName = DemarshallingUtils.safeString(object,"localizedName");
		cdb.marshallInitialization(id, localizedName);
	}

	public static List listUnMarshall(EJValue o, MarshallingSession ctx, String encName) {
		if (o.isArray() != null) {
			EJArray array = o.isArray();
			List list = new ArrayList();
			Marshaller<Object> marshaller = ctx.getMarshallerInstance(encName);
			for (int i = 0, ll = array.size(); i < ll; i++) {
				list.add(marshaller.demarshall(array.get(i), ctx));
			}
			return list;
		} else return new ArrayList();
	}

	public static boolean containsAndNotNull(EJObject obj, String key) {
		return obj.containsKey(key) && (!obj.get(key).isNull());
	}

	
	
	public static String matchAndReplacePattern(char[] longString, int position, char[] pattern, String replaceString) {
		for (int i = 0,j=position; i < pattern.length; i++,j++) {
			if (longString[j] != pattern[i]) {
				return null;
			}
		}
		return replaceString;
	}


	
	
	
	public static String unescape(String strVal) {
		StringBuilder builder = new StringBuilder();
		char[] chars = strVal.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			char ch = chars[i];
			switch(ch) {
				case '\\':
					if (i < chars.length-1) {
						char nextChar = chars[++i];
						switch(nextChar) {
							case 'n':
								builder.append('\n');
							break;
							case '"':
								builder.append('\"');
							break;
							default:
								builder.append(ch);
								builder.append(nextChar);
							break;
						}
					} else {
						//last
						builder.append(ch);
					}
				break;
				default:
					builder.append(ch);
				break;
			}
			
		}
		return builder.toString();
	}
	
	public static String safeString(EJObject obj, String key) {
		if (containsAndNotNull(obj, key)) {
			if (obj.get(key).isString() == null) {
				throw new IllegalStateException("expect string type for the key '"+key+"'");
			}
			return obj.get(key).isString().stringValue();
		}
		return null;
			
	}
	
	public static int safeInteger(EJObject obj, String key) {
		return containsAndNotNull(obj, key) ? obj.get(key).isNumber().intValue() :  0;
	}
	
	public static boolean safeBool(EJObject obj, String key) {
		return containsAndNotNull(obj, key) ? obj.get(key).isBoolean().booleanValue() :  false;
	}

	
	public static void main(String[] args) {
		String strVal = "prvniradek \\n druhyradek \\\" \\ntreti \\radek \\n";
		String string = unescape(strVal);
		
		System.out.println(strVal);
		System.out.println(string);
		
//		String demString = unescape(strVal);
//		System.out.println(demString);
	}
}
